<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>游客信息管理</title>
  <!--引入的vue.js-->
  <script src="/js/vue.js"></script>
  <!--引入elementUI的css-->
  <link type="text/css" rel="stylesheet" href="/css/index.css">
  <!--引入elementUI的js-->
  <script src="/js/index.js"></script>
  <!--引入axios.js-->
  <script src="/js/axios.min.js"></script>

  <style>
    .search-container {
      margin-bottom: 20px;
      padding: 15px;
      background-color: #f5f7fa;
      border-radius: 4px;
    }
    .form-section {
      border-bottom: 1px solid #ebeef5;
      margin-bottom: 20px;
      padding-bottom: 15px;
    }
    .form-section-title {
      font-weight: bold;
      color: #409EFF;
      margin-bottom: 15px;
      font-size: 16px;
    }
    .table-container {
      margin-top: 20px;
    }
    .action-buttons {
      display: flex;
      gap: 5px;
    }
    .pagination-container {
      margin-top: 20px;
      text-align: right;
    }
    .dialog-footer {
      text-align: right;
    }
    .avatar-uploader .el-upload {
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
    }
    .avatar-uploader .el-upload:hover {
      border-color: #409EFF;
    }
    .avatar-uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 178px;
      height: 178px;
      line-height: 178px;
      text-align: center;
    }
    .avatar {
      width: 178px;
      height: 178px;
      display: block;
    }
    .visitor-avatar {
      width: 50px;
      height: 50px;
      object-fit: cover;
    }
  </style>
</head>
<body>
<div id="app">
  <!-- 搜索框 -->
  <div class="search-container">
    <el-row :gutter="10">
      <el-col :span="4">
        <el-input v-model="searchForm.visitorId" placeholder="请输入游客ID" clearable></el-input>
      </el-col>
      <el-col :span="4">
        <el-input v-model="searchForm.visitorsName" placeholder="请输入游客名称" clearable></el-input>
      </el-col>
      <el-col :span="4">
        <el-input v-model="searchForm.phoneNumber" placeholder="请输入手机号" clearable></el-input>
      </el-col>
      <el-col :span="4">
        <el-input v-model="searchForm.realName" placeholder="请输入真实姓名" clearable></el-input>
      </el-col>
      <el-col :span="4">
        <el-button type="primary" icon="el-icon-search" @click="search">搜索</el-button>
      </el-col>
    </el-row>
  </div>

  <!-- 列表数据 -->
  <div class="table-container">
    <el-table :data="tableData" style="width: 100%" v-loading="loading" stripe>
      <el-table-column prop="visitorId" label="游客ID" width="80"></el-table-column>
      <el-table-column prop="visitorsName" label="游客名称" width="120"></el-table-column>
      <el-table-column prop="phoneNumber" label="手机号" width="120"></el-table-column>
      <el-table-column prop="email" label="邮箱" width="150"></el-table-column>
      <el-table-column prop="realName" label="真实姓名" width="100"></el-table-column>
      <el-table-column prop="gender" label="性别" width="80">
        <template slot-scope="scope">
          <span v-if="scope.row.gender === 1">男</span>
          <span v-else-if="scope.row.gender === 2">女</span>
          <span v-else>未设置</span>
        </template>
      </el-table-column>
      <el-table-column prop="avatar" label="头像" width="80">
        <template slot-scope="scope">
          <img v-if="scope.row.avatar"
               :src="scope.row.avatar"
               class="visitor-avatar"
               @error="$event.target.src='/img/默认.jpg'">
          <span v-else>无头像</span>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" width="160">
        <template slot-scope="scope">
          {{ scope.row.createTime | formatDate }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="210" fixed="right">
        <template slot-scope="scope">
          <div class="action-buttons">
            <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
          </div>
        </template>
      </el-table-column>
    </el-table>
  </div>


  <!-- 分页 -->
  <div class="pagination-container">
    <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[5,10,15,20,100,200]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total">
    </el-pagination>
  </div>
</div>

<script>
  new Vue({
    el: "#app",
    data() {
      return {
        activeIndex: "1",
        tableData: [], // 列表数据
        currentPage: 1, // 分页参数 第几页
        pageSize: 10, // 分页参数 每页显示的总条数
        total: 0, // 分页参数，列表总条数
        loading: false, // 加载状态
        searchForm: {}, // 搜索表单
        dialogFormVisible: false, // 弹窗显示状态
        title: '添加游客', // 弹窗标题
        form: { // 表单数据
          visitorId: null,
          visitorsName: '',
          phoneNumber: '',
          email: '',
          password: '',
          realName: '',
          gender: null,
          idCard: '',
          birthday: '',
          avatar: ''
        },
        formLabelWidth: '120px',
        rules: { // 表单验证规则
          visitorsName: [
            { required: true, message: '请输入游客名称', trigger: 'blur' },
            { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
          ],
          phoneNumber: [
            { required: true, message: '请输入手机号', trigger: 'blur' },
            { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
          ],
          email: [
            { required: false, message: '请输入邮箱地址', trigger: 'blur' },
            { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
          ],
          password: [
            { required: true, message: '请输入密码', trigger: 'blur' },
            { min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
          ],
          realName: [
            { required: false, message: '请输入真实姓名', trigger: 'blur' },
            { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
          ],
          idCard: [
            { required: false, message: '请输入身份证号', trigger: 'blur' },
            { pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/, message: '请输入正确的身份证号', trigger: 'blur' }
          ]
        }
      }
    },
    // 页面加载时执行
    created() {
      this.loadData();
    },
    filters: {
      formatDate(value) {
        if (!value) return '';
        const date = new Date(value);
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        const hours = String(date.getHours()).padStart(2, '0');
        const minutes = String(date.getMinutes()).padStart(2, '0');
        const seconds = String(date.getSeconds()).padStart(2, '0');
        return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
      }
    },
    methods: {
      // 加载列表数据
      loadData() {
        this.loading = true;
        const _this = this;
        axios.post('/visitors/queryByPage', {
          pageNo: this.currentPage,
          pageSize: this.pageSize,
          data: this.searchForm
        })
            .then(response => {
              if (response.data.code === 200) {
                _this.tableData = response.data.data.list;
                _this.total = response.data.data.total;
              } else {
                _this.$message.error('数据加载失败：' + (response.data.msg || '未知错误'));
              }
            })
            .catch(error => {
              console.error('加载数据出错：', error);
              _this.$message.error('网络错误，无法加载数据');
            })
            .finally(() => {
              _this.loading = false;
            });
      },
      // 每页条数改变
      handleSizeChange(val) {
        this.pageSize = val;
        this.loadData();
      },
      // 当前页改变
      handleCurrentChange(val) {
        this.currentPage = val;
        this.loadData();
      },
      // 搜索
      search() {
        this.currentPage = 1;
        this.loadData();
      },
      // 提交表单
      submitForm(formRef) {
        this.$refs[formRef].validate(valid => {
          if (valid) {
            const uri = this.title === '更新游客' ? '/visitors/update' : '/visitors/add';
            const _this = this;

            // 处理日期格式
            const formData = {...this.form};
            if (formData.birthday) {
              // 确保日期格式正确
              if (typeof formData.birthday === 'string') {
                // 已经是字符串格式，不需要转换
              } else if (formData.birthday instanceof Date) {
                // 从日期对象转换为字符串
                formData.birthday = formData.birthday.toISOString().split('T')[0];
              }
            }

            axios.post(uri, formData)
                .then(response => {
                  _this.handleResponse(response);
                })
                .catch(error => {
                  _this.handleError(error);
                });
          } else {
            console.log('表单验证失败');
            return false;
          }
        });
      },
      // 响应处理
      handleResponse(response) {
        if (response.data.code === 200) {
          this.$message({
            message: '操作成功',
            type: 'success'
          });
          this.loadData();
          this.dialogFormVisible = false;
        } else {
          this.$message.error('操作失败：' + (response.data.msg || '未知错误'));
        }
      },
      // 错误处理
      handleError(error) {
        console.error('操作出错：', error);
        this.$message.error('网络错误或服务器异常，请稍后重试');
      },
      // 重置表单
      resetForm(formRef) {
        this.$refs[formRef].resetFields();
      },
      // 添加游客
      handleAdd() {
        this.dialogFormVisible = true;
        this.title = '添加游客';
        // 重置表单默认值
        this.form = {
          visitorId: null,
          visitorsName: '',
          phoneNumber: '',
          email: '',
          password: '',
          realName: '',
          gender: null,
          idCard: '',
          birthday: '',
          avatar: ''
        };
      },
      // 编辑游客
      handleEdit(index, row) {
        this.dialogFormVisible = true;
        this.title = '更新游客';
        // 深拷贝避免原数据被修改
        this.form = JSON.parse(JSON.stringify(row));
        // 处理日期格式
        if (this.form.birthday) {
          this.form.birthday = new Date(this.form.birthday).toISOString().split('T')[0];
        }
      },
      // 删除游客
      handleDelete(index, row) {
        this.$confirm('此操作将永久删除该游客信息，是否继续？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
            .then(() => {
              const _this = this;
              axios.delete('/visitors/deleteById', {
                params: {
                  visitorId: row.visitorId
                }
              })
                  .then(response => {
                    if (response.data.code === 200) {
                      _this.$message.success('删除成功');
                      _this.loadData();
                    } else {
                      _this.$message.error('删除失败：' + (response.data.msg || '未知错误'));
                    }
                  })
                  .catch(error => {
                    console.error('删除出错：', error);
                    _this.$message.error('网络错误，删除失败');
                  });
            })
            .catch(() => {
              this.$message.info('已取消删除');
            });
      },
      // 弹窗关闭前回调
      handleDialogClose(done) {
        this.$confirm('确认关闭？未保存的数据将会丢失')
            .then(() => done())
            .catch(() => {});
      },
      // 头像上传成功
      handleAvatarSuccess(res, file) {
        if (res.code === 200) {
          this.form.avatar = res.data.url;
          this.$message.success('头像上传成功');
        } else {
          this.$message.error('头像上传失败：' + (res.msg || '未知错误'));
        }
      },
      // 头像上传失败
      handleAvatarError(err) {
        this.$message.error('头像上传失败：' + (err.message || '网络异常'));
      },
      // 头像上传前校验
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpeg' || file.type === 'image/png';
        const isLt2M = file.size / 1024 / 1024 < 2;

        if (!isJPG) {
          this.$message.error('上传头像只能是 JPG 或 PNG 格式！');
        }
        if (!isLt2M) {
          this.$message.error('上传头像大小不能超过 2MB！');
        }
        return isJPG && isLt2M;
      }
    }
  });
</script>
</body>
</html>